package tech

import "slices"

func metWithWeakLink(head, tail GroupItem) bool {
	return head.cand == tail.cand && isSameHouse([]*Cell{head.group[0], tail.group[0]})
}

func (g *Grid) xCycleGetWeaks(node *ChainNode) []GroupItem {
	weaks := []GroupItem{}
	for _, cell := range g.candSeenCells(node.item.cand, node.item.group[0]) {
		weak := GroupItem{node.item.cand, [9]*Cell{cell}}

		weaks = append(weaks, weak)
	}
	return weaks
}

func (g *Grid) xCycleGetStrongs(node *ChainNode) []GroupItem {
	strongs := []GroupItem{}
	for _, cell := range g.candSeenCells(node.item.cand, node.item.group[0]) {
		houses := g.getSameHouses([]*Cell{node.item.group[0], cell})
		if !isOnlyInHouses(node.item.cand, []*Cell{cell, node.item.group[0]}, houses) {
			continue
		}
		strong := GroupItem{node.item.cand, [9]*Cell{cell}}
		//if existSingleItemCell(node, strong) {
		//	continue
		//}
		strongs = append(strongs, strong)
	}
	return strongs
}

func (s *Solve) XCycle3(g *Grid) (used bool, results []*Result) {
	c := Chain{
		g:            g,
		strategyName: "X-Cycle",
		getWeaks:     g.xCycleGetWeaks,
		getStrongs:   g.xCycleGetStrongs,
		closeCycle:   metWithWeakLink,
		canRemove:    g.canRemoveSingle,
	}

	return c.ExecStrategy3()
}

func (g *Grid) metWithStrongLink(head, tail GroupItem) bool {
	node := ChainNode{nil, head}
	items := g.xCycleGetStrongs(&node)
	return slices.Contains(items, tail)

}
func (s *Solve) XCycle2(g *Grid) (used bool, results []*Result) {
	c := Chain{
		g:            g,
		strategyName: "X-Cycle2",
		getWeaks:     g.xCycleGetWeaks,
		getStrongs:   g.xCycleGetStrongs,
		closeCycle:   g.metWithStrongLink,
		canRemove:    g.canRemoveSingle,
	}

	return c.ExecStrategy2()
}
